﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Text;

namespace Workflows.Components.ETL
{
    /// <summary>
    /// 
    /// </summary>
    public class WebRequestParser
    {
        private WebRequest _WebReq;
        /// <summary></summary>
        public WebRequest WebReq
        {
            get
            {
                return this._WebReq;
            }
            set
            {
                this._WebReq = value;
            }
        }

        private string _InterceptedMessage;
        /// <summary></summary>
        public string InterceptedMessage
        {
            get
            {
                return this._InterceptedMessage;
            }
            set
            {
                this._InterceptedMessage = value;
            }
        }

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="interceptedMessage"></param>
        public WebRequestParser(string interceptedMessage)
        {
            this._InterceptedMessage = interceptedMessage;
            this._WebReq = this.ParseInterceptedMessage(this._InterceptedMessage);
        }

        private WebRequest ParseInterceptedMessage(string message)
        {
            // TODO: parse intercepted message into web request
            WebRequest webRequest=new WebRequest();
            string requestUrl = this.GetRequestedUrl(message);
            string baseUrl = string.Empty;
            string pageUrl = string.Empty;
            List<WebParameter> parameters=new List<WebParameter>();
            WebRequestIntercepter interpreter=new WebRequestIntercepter();
            interpreter.ParseUrl(requestUrl,ref baseUrl,ref pageUrl, ref parameters);
            webRequest.BaseUrl = baseUrl;
            webRequest.RequestPagePath = pageUrl;
            webRequest.Method = this.ParseMethod(message);
            this.ParseFormParameters(message,ref parameters);
            webRequest.Parameters = parameters;

            webRequest.Cookies = this.ParseCookies(message);
            webRequest.Credential = this.ParseCredential(message);
            webRequest.Protocol = this.ParseProtocol(message);
            webRequest.WebRequestID = Guid.NewGuid();
            return webRequest;
        }

        private void ParseFormParameters(string message, ref List<WebParameter> parameters)
        {
            string[] lines = message.Split(new char[] {'\n'});
            string postedContent = string.Empty;
            StringBuilder buffer=new StringBuilder();
            bool foundLineSpacer = false;
            for(int i=0;i<lines.Length;i++)
            {
                if(!foundLineSpacer && lines[i].Trim().Length >0)
                {
                    
                }
                else if(lines[i].Trim().Length==0)
                {
                    foundLineSpacer = true;
                }
                else if(foundLineSpacer)
                {
                    buffer.Append(lines[i] + "\n");
                }
            }
            if(foundLineSpacer && buffer.Length>0)
            {
                postedContent = buffer.ToString();
                string[] lines2 = postedContent.Split(new char[] {'\n'});
                foreach(string line in lines2)
                {
                    if(line.Trim().Length>0)
                    {
                        string[] paramPairs = line.Split(new char[] {'&'});
                        foreach(string paramPair in paramPairs)
                        {
                            string[] pair = paramPair.Split(new char[] {'='});
                            if(pair.Length==2)
                            {
                                WebParameter webParam=new WebParameter();
                                webParam.ParameterName = pair[0];
                                webParam.ParameterValue = pair[1];
                                webParam.ParemeterType = WebParameterType.InputText;
                                parameters.Add(webParam);
                            }
                        }
                    }
                }
            }
        }

        private WebRequest.HttpMethod ParseMethod(string message)
        {
            WebRequest.HttpMethod method = WebRequest.HttpMethod.GET;
            string[] lines = message.Split(new char[] { '\n' });
            if(lines !=null && lines.Length>0 && !string.IsNullOrEmpty(lines[0]))
            {
                string firstLine = lines[0];
                string[] words = firstLine.Split(new char[] {' '});
                if(words.Length>0 && words[0].ToLower()=="post")
                {
                    method = WebRequest.HttpMethod.POST;
                }
                else if (words.Length > 0 && words[0].ToLower() == "rest")
                {
                    method = WebRequest.HttpMethod.REST;
                }
            }
            return method;
        }

        private NetworkCredential ParseCredential(string message)
        {
            return new NetworkCredential();
        }

        private List<Cookie> ParseCookies(string message)
        {
            List<Cookie> cookies=new List<Cookie>();
            string[] lines = message.Split(new char[] { '\n' });
            for (int i = 0; i < lines.Length; i++)
            {
                if (lines[i].Trim().Length > 0)
                {
                    if(lines[i].ToLower().StartsWith("cookie:"))
                    {
                        string cookieVar = lines[i].Substring("cookie:".Length).Trim();
                        string[] pair = cookieVar.Split(new char[] {'='});
                        if(pair.Length==2)
                        {
                            Cookie cookie=new Cookie(pair[0],pair[1]);
                            cookies.Add(cookie);
                        }
                    }
                }
                else if (lines[i].Trim().Length == 0)
                {
                    break;
                }
            }
            return cookies;
        }

        private WebRequestProtocol ParseProtocol(string message)
        {
            string[] lines = message.Split(new char[] {'\n'});
            string firstLine = lines[0];
            return WebRequestProtocol.http;
        }

        private string GetRequestedUrl(string message)
        {
            string[] lines = message.Split(new char[] { '\n' });
            string firstLine = lines[0];
            string[] textTokens = firstLine.Split(new char[] {' '});
            string url = textTokens[1];
            return url;
        }
    }
}
